#include "page_base.h"

namespace Page
{

    GxEPD2_3C<GxEPD2_750c_Z08, SCREEN_HEIGHT_STEP> Base::display = GxEPD2_3C<GxEPD2_750c_Z08, SCREEN_HEIGHT_STEP>(GxEPD2_750c_Z08(/*CS=15*/ PIN_SPI_CS, /*DC=4*/ PIN_SPI_DC, /*RST=2*/ PIN_SPI_RST, /*BUSY=5*/ PIN_SPI_BUSY));

    Base::Base()
    {
        // one common reset for all displays
        Base::display.init(0);
        Base::display.setRotation(0);
        // Base::display.setRotation(2);
        Base::display.setFullWindow();

        u8g2Fonts.begin(Base::display);
    }

    const uint8_t *Base::_getFont(int fontSize)
    {
        typedef std::map<int, const uint8_t *> TYPE_FONTS_MAP;
        TYPE_FONTS_MAP fontsMap;
        fontsMap[8] = u8g2_font_helvR08_tr;
        fontsMap[10] = u8g2_font_helvR10_tr;
        fontsMap[12] = u8g2_font_helvR12_tr;
        fontsMap[14] = u8g2_font_helvR14_tr;
        fontsMap[18] = u8g2_font_helvR18_tr;
        fontsMap[24] = u8g2_font_helvR24_tr;

        TYPE_FONTS_MAP::iterator fontIter = fontsMap.find(fontSize);
        if (fontIter == fontsMap.end())
        {
            Serial2.printf("font not find: %s \n", fontSize);
            return u8g2_font_helvR18_tr;
        }
        else
        {
            return fontIter->second;
        }
    }

    void Base::_displayTextCenter(String text, int fontSize, int centerX, int centerY)
    {
        u8g2Fonts.setFont(_getFont(fontSize));

        // u8g2Fonts.setFontMode(1);
        u8g2Fonts.setFontDirection(0);
        u8g2Fonts.setForegroundColor(GxEPD_BLACK);
        u8g2Fonts.setBackgroundColor(GxEPD_WHITE); // apply Adafruit GFX color
        // u8g2Fonts.setFont(font);                   // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
        int16_t tw = u8g2Fonts.getUTF8Width(text.c_str()); // text box width
        int16_t ta = u8g2Fonts.getFontAscent();            // positive
        int16_t td = u8g2Fonts.getFontDescent();           // negative; in mathematicians view
        int16_t th = ta - td;                              // text box height
        // uint16_t x = (layoutBoardTodayWidth - tw) / 2 - layoutBoardTodayX;
        // uint16_t y = layoutBoardTodayHeight * 3 / 4 - th / 2 + ta - layoutBoardTodayY;
        uint16_t x = centerX - (tw / 2);
        uint16_t y = centerY + (th / 2);
        u8g2Fonts.setCursor(x, y);
        u8g2Fonts.print(text);
    }

    void Base::_displayTempCenter(float temp, int fontSize, int centerX, int centerY)
    {

        int sizeSymbol = fontSize / 2.5;
        int radiusSymbol = sizeSymbol / 2;
        int placeholderSymbol = fontSize / 2;
        int floatWidth = 0, floatHeight = 0;

        char text[40];
        snprintf(text, sizeof(text), "%.0f", temp);
        u8g2Fonts.setFont(_getFont(fontSize));

#pragma region copyfrom _displayTextCenter

        // u8g2Fonts.setFontMode(1);
        u8g2Fonts.setFontDirection(0);
        u8g2Fonts.setForegroundColor(GxEPD_BLACK);
        u8g2Fonts.setBackgroundColor(GxEPD_WHITE); // apply Adafruit GFX color
        // u8g2Fonts.setFont(font);                   // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
        int16_t tw = u8g2Fonts.getUTF8Width(text); // text box width
        int16_t ta = u8g2Fonts.getFontAscent();    // positive
        int16_t td = u8g2Fonts.getFontDescent();   // negative; in mathematicians view
        int16_t th = ta - td;                      // text box height
        // uint16_t x = (layoutBoardTodayWidth - tw) / 2 - layoutBoardTodayX;
        // uint16_t y = layoutBoardTodayHeight * 3 / 4 - th / 2 + ta - layoutBoardTodayY;
        uint16_t x = centerX - ((tw + placeholderSymbol) / 2);
        uint16_t y = centerY + (th / 2);
        u8g2Fonts.setCursor(x, y);
        u8g2Fonts.print(text);

#pragma endregion

        int topRightX = centerX + (tw + placeholderSymbol) / 2;
        int topRightY = centerY - th / 5;
        if (fontSize == 24)
        {
            Serial2.printf("font ta:%d td:%d\n", ta, td);
            Serial2.printf("font w:%d h:%d\n", floatWidth, floatHeight);
            Serial2.printf("symbol x:%d y:%d\n", topRightX, topRightY);
        }
        Base::display.drawCircle(topRightX - radiusSymbol, topRightY - radiusSymbol, radiusSymbol, GxEPD_BLACK);
    }

    void Base::_displayIconCenter(String iconName, int size, int centerX, int centerY)
    {
        const unsigned char *_iconBitmaps = Helper::getIcon(iconName, size);
        int x = centerX - size / 2;
        int y = centerY - size / 2;
        Base::display.drawBitmap(x, y, _iconBitmaps, size, size, GxEPD_WHITE, GxEPD_BLACK);
    }

    void Base::_displayFloatCenter(float num, String format, int fontSize, int centerX, int centerY)
    {
        char text[40];
        snprintf(text, sizeof(text), format.c_str(), num);
        _displayTextCenter(text, fontSize, centerX, centerY);
    }

    void Base::_displayTextLeft(String text, int fontSize, int leftX, int centerY)
    {
        u8g2Fonts.setFont(_getFont(fontSize));

        // u8g2Fonts.setFontMode(1);
        u8g2Fonts.setFontDirection(0);
        u8g2Fonts.setForegroundColor(GxEPD_BLACK);
        u8g2Fonts.setBackgroundColor(GxEPD_WHITE); // apply Adafruit GFX color
        // u8g2Fonts.setFont(font);                   // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
        int16_t tw = u8g2Fonts.getUTF8Width(text.c_str()); // text box width
        int16_t ta = u8g2Fonts.getFontAscent();            // positive
        int16_t td = u8g2Fonts.getFontDescent();           // negative; in mathematicians view
        int16_t th = ta - td;                              // text box height
        // uint16_t x = (layoutBoardTodayWidth - tw) / 2 - layoutBoardTodayX;
        // uint16_t y = layoutBoardTodayHeight * 3 / 4 - th / 2 + ta - layoutBoardTodayY;
        uint16_t x = leftX;
        uint16_t y = centerY + (th / 2);
        u8g2Fonts.setCursor(x, y);
        u8g2Fonts.print(text);
    }
    
    void Base::_displayTempLeft(float temp, int fontSize, int leftX, int centerY)
    {
            int sizeSymbol = fontSize / 2.5;
        int radiusSymbol = sizeSymbol / 2;
        int placeholderSymbol = fontSize / 2;
        int floatWidth = 0, floatHeight = 0;

        char text[40];
        snprintf(text, sizeof(text), "%.0f", temp);
        u8g2Fonts.setFont(_getFont(fontSize));

#pragma region copyfrom _displayTextCenter

        // u8g2Fonts.setFontMode(1);
        u8g2Fonts.setFontDirection(0);
        u8g2Fonts.setForegroundColor(GxEPD_BLACK);
        u8g2Fonts.setBackgroundColor(GxEPD_WHITE); // apply Adafruit GFX color
        // u8g2Fonts.setFont(font);                   // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
        int16_t tw = u8g2Fonts.getUTF8Width(text); // text box width
        int16_t ta = u8g2Fonts.getFontAscent();    // positive
        int16_t td = u8g2Fonts.getFontDescent();   // negative; in mathematicians view
        int16_t th = ta - td;                      // text box height
        // uint16_t x = (layoutBoardTodayWidth - tw) / 2 - layoutBoardTodayX;
        // uint16_t y = layoutBoardTodayHeight * 3 / 4 - th / 2 + ta - layoutBoardTodayY;
        uint16_t x = leftX;
        uint16_t y = centerY + (th / 2);
        u8g2Fonts.setCursor(x, y);
        u8g2Fonts.print(text);

#pragma endregion

        int topRightX = leftX + (tw + placeholderSymbol);
        int topRightY = centerY - th / 5;
        if (fontSize == 24)
        {
            Serial2.printf("font ta:%d td:%d\n", ta, td);
            Serial2.printf("font w:%d h:%d\n", floatWidth, floatHeight);
            Serial2.printf("symbol x:%d y:%d\n", topRightX, topRightY);
        }
        Base::display.drawCircle(topRightX - radiusSymbol, topRightY - radiusSymbol, radiusSymbol, GxEPD_BLACK);
    }
    
    void Base::_displayIntLeft(int num, String format, int size, int leftX, int centerY)
    {
        char text[40];
        snprintf(text, sizeof(text), format.c_str(), num);
        _displayTextLeft(text, size, leftX, centerY);
    }

    void Base::_displayBatteryCenter(float battery,  int centerX, int centerY)
    {
        int fontSize = 12;

        // battery body
        int _bodyWidth = 40;
        int _bodyHeight = 22;
        int _bodyX = centerX - _bodyWidth / 2;
        int _bodyY = centerY - _bodyHeight / 2+2;
        int _bodyRound = 2;
       

        // battery positive
        int _bpWidth = 3;
        int _bpHeight = 8;
        int _bpX = _bodyX - _bpWidth + 1;
        int _bpY = centerY - _bpHeight / 2+1;
        int _bpRound = 1;

        // draw
        display.fillRoundRect(_bpX, _bpY, _bpWidth, _bpHeight, _bpRound, GxEPD_BLACK);
        display.drawRoundRect(_bodyX, _bodyY, _bodyWidth, _bodyHeight, _bodyRound, GxEPD_BLACK);
        //_displayFloatCenter(battery, "%3.0f%%", 12, 100, 40);
        _displayFloatCenter(battery, "%3.0f", 12, centerX - 2, centerY);
    }

}